import std.stdio;
import std.socket;
import core.thread;
import std.string;
import std.conv;
import std.regex;

import mysock;

int main(char[][] args) {
    ushort port = 1000;
    if(args.length >= 2)
        port = parse!(ushort)(args[1]);

    auto srv = new MySocket(port);
    debug log(`Listen on port ` ~ to!(string)(port));
    
    for(auto cli = srv.accept(); srv.isAlive(); cli = srv.accept()){
        debug log(`Client come from ` ~ cli.remoteAddr());
        ServiceClientThread t = new ServiceClientThread(cli);
debug {
        t.start_debug();
} else {    
        t.start();
}        
    }
    return 0;
}

void log(string s)
{
    synchronized writefln(s);
}

class ServiceClientThread : Thread
{
    private MySocket cli;

    this(MySocket remote){
        cli = remote;
debug {

} else {    
        isDaemon(true);
        super(&run);
}
    }//this

debug    
    public void start_debug(){
        run();
    }
    
    void run()
    {
        debug log(`Service thread STARTED! Reading...`);
        string request = cli.readLine();
        debug log(`CLIENT: ` ~ request);
        
        auto req_match = match(request, `^(\w+)\s+((\w+)://([^/]+)(\S+))\s*(.*)`); // CMD=$1 URL=$2 proto=$3 Host:port=$4 Resource=$5
        if (req_match.captures.length < 1) return;
        string cmd = toupper(req_match.captures[1]);// service GET/POST only
        if (cmd != `GET` && cmd != `POST`) throw new Exception(`Wrong command!`);
        string URL = req_match.captures[2];
        string proto = toupper(req_match.captures[3]);// serivce HTTP only
        string host = req_match.captures[4].idup;// idup needed?
        ushort port = 80;// standard http port
        int i = find(host, `:`);
        if (i > 0) {
            port = parse!(ushort)(host[i+1 .. $]);
            host = host[0 .. i].idup;
        }
        string resource = req_match.captures[5].idup;
        
        //debug log(`CMD=`~cmd~` URL=`~URL~` proto=`~proto~` host=`~host~` port=`~to!(string)(port)~` res=`~resource);
        // read header
        string[string] hdr;
        for(auto s = cli.readLine(); s != ``; s = cli.readLine()) {
            auto z = std.regexp.RegExp(`:\s+`).split(s);
            if (z.length != 2) {
                debug log(`Skipped wrong header [`~s~`]`);
                continue;
            }
            hdr[toupper(z[0])] = z[1];
        }

        debug foreach(s; hdr.keys)
            log(`Hdr[`~s~`] = "`~hdr[s]~`"`);

        //TODO: read POST data (if needed)
        //TODO: filter URL
        //TODO: load data (if not in cache)
        //TODO: transfer data to client
        
//        cli.writeLine(`hello! ` ~ request);
        cli.close();
    }
}
